package com.demo.lambda;




import java.util.*;
import java.util.function.*;

public class LambdaTest {

    public void test0() {
        /**
         *注意：
         *   1.lambda体中调用方法的参数列表与返回值类型，要与函数式接口中抽象方法的函数列表和返回值类型保持一致！
         *   2.若lambda参数列表中的第一个参数是实例方法的调用者，而第二个参数是实例方法的参数时，可以使用ClassName::method
         *
         */
        Consumer<Integer> con = (x) -> System.out.println(x);
        con.accept(100);

        // 方法引用-对象::实例方法
        Consumer<Integer> con2 = System.out::println;
        con2.accept(200);

        // 方法引用-类名::静态方法名
        BiFunction<Integer, Integer, Integer> biFun = (x, y) -> Integer.compare(x, y);
        BiFunction<Integer, Integer, Integer> biFun2 = Integer::compare;
        Integer result = biFun2.apply(100, 200);

        // 方法引用-类名::实例方法名
        BiFunction<String, String, Boolean> fun1 = (str1, str2) -> str1.equals(str2);
        BiFunction<String, String, Boolean> fun2 = String::equals;
        Boolean result2 = fun2.apply("hello", "world");
        System.out.println(result2);
    }


    // Consumer<T> :消费型接口
    // void  accept(T t)

    public void test1() {
        ConsummerTest(100, (x) -> System.out.println("消费" + x + "元"));
        Consumer<Integer> consummer = (x) -> System.out.println(x);
        consummer.accept(10);
        Consumer<Integer> consummer1 = System.out::println;
        consummer1.accept(20);
    }

    public void ConsummerTest(int n, Consumer<Integer> consumer) {
        consumer.accept(n);
    }


    //Supplier<T> :供给型接口
    // T get()

    public void test2() {
        List<Integer> list = SupplierTest(10, () -> new Random().nextInt(100));
        System.out.println(list);
    }

    public List<Integer> SupplierTest(int n, Supplier<Integer> supplier) {
        List<Integer> list = new ArrayList<>();
        for (int i = 0; i < n; i++) {
            list.add(supplier.get());
        }
        return list;
    }


    // Function<T,R> :函数型接口
    //R  apply(T t)

    public void test3() {
        int n = FunctionalTest("1233", (x) -> Integer.parseInt(x));
        System.out.println(n);
    }

    public int FunctionalTest(String str, Function<String, Integer> f) {
        int n = f.apply(str);
        return n;
    }


    //Predicate<T> :断言型接口
    //  boolean  test(T t)

    public void test4() {
        List<String> list = Arrays.asList("aa", "bbb", "cccc");
        List<String> list1 = PredicateTest(list, (x) -> {
            return x.length() > 2 ? true : false;
        });
        System.out.println(list1);
    }

    public List<String> PredicateTest(List<String> list, Predicate<String> predicate) {
        List<String> re = new ArrayList<>();
        for (String s : list) {
            if (predicate.test(s)) {
                re.add(s);
            }
        }
        return re;
    }



    public void test() {
        String str = getValue("abcd", (x) -> x.toUpperCase());
        System.out.println(str);
        String s = getValue("abcd", (x) -> x.replaceAll("\\w", "1"));
        System.out.println(s);
    }

    public String getValue(String s, lambadInterface l) {
        return l.getValue(s);
    }


    public static void main(String[] args) {
















      /*  List<String> list=new ArrayList<>();
        list.add("c");
        list.add("g");*/

        List<Person> list = new ArrayList<>();
        list = Arrays.asList(
                new Person("a", 20),
                new Person("b", 15),
                new Person("c", 10),
                new Person("d", 20)
        );

        Collections.sort(list, (x, y) -> {
            if (x.getAge() == y.getAge()) {
                return x.getName().compareTo(y.getName());
            } else {
                return x.getAge() - y.getAge();
            }
        });


        for (Person p : list) {
            System.out.println(p.toString());
        }
    }

    public static List<Person> fun(List<Person> perList, LambdaInter lambdaInter) {
        List<Person> list = new ArrayList<>();
        for (Person p : perList) {
            if (lambdaInter.test(p)) {
                list.add(p);
            }
        }
        return list;
    }
}

interface LambdaInter {
    public boolean test(Person p);
}

class Person {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

